#ifdef SU1
#define _GLIBCXX_DEBUG
#endif

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cstring>
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <stack>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define forn(i, n) for (int i = 0; i < int(n); i++)
#define forl(i, n) for (int i = 1; i <= int(n); i++)
#define ford(i, n) for (int i = int(n) - 1; i >= 0; i--)
#define fore(i, l, r) for (int i = int(l); i <= int(r); i++)
#define pb(a) push_back(a)
#define mp(x, y) make_pair((x), (y))
#define sz(a) (int) (a).size()
#define all(a) (a).begin(), (a).end()
#define ft first
#define sc second
#define x first
#define y second

template<typename X> inline X abs(const X& a) { return a < 0 ? -a : a; }
template<typename X> inline X sqr(const X& a) { return a * a; }

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

const int INF = int(1e9);
const li INF64 = li(1e18);
const ld PI = acosl(ld(-1));
const ld EPS = 1e-9;

ld readLd() {
	double x;
	assert(scanf("%lf", &x) == 1);
	return ld(x);
}

const int N = 100500;
int n;
ld x[N], r[N];

inline bool read()
{
	assert(scanf("%d", &n) == 1);
	if (n == 0) return false;
	forn(i, n) {
		x[i] = readLd();
		r[i] = readLd();
	}
	return true;
}

ld getD(ld r1, ld d, ld r2) {
	ld cs = -(r2 * r2 - r1 * r1 - d * d) / (2 * r1 * d);
	return r1 * cs;
}

ld lf[N], rg[N];

ld can(ld h) {
	ld h2 = h / 2;
	bool st = false;
	ld stX = 0;
	ld mx = 0;
	forn(i, n) {
		//cerr << "I = " << i << endl;
		//cerr << lf[i] << ' ' << rg[i] << endl;
		if (h2 > r[i])
			continue;
		ld dd = sqrtl(r[i] * r[i] - h2 * h2);
		ld x1 = x[i] - dd;
		ld x2 = x[i] + dd;
		//cerr << x1 << ' ' << x2 << endl;
		if (lf[i] <= x1 && x1 <= rg[i]) {
			//cerr << "EV " << x1 << endl;
			if (st) {
				mx = max(mx, x1 - stX);
				st = false;
			} else {
				st = true;
				stX = x1;
			}
		}
		if (lf[i] <= x2 && x2 <= rg[i]) {
			//cerr << "EV " << x2 << endl;
			if (st) {
				mx = max(mx, x2 - stX);
				st = false;
			} else {
				st = true;
				stX = x2;
			}
		}
	}
	return mx;
}

inline void solve()
{
	forn(i, n) {
		lf[i] = x[i] - r[i];
		rg[i] = x[i] + r[i];
		if (i > 0) {
			lf[i] = x[i] - getD(r[i], x[i] - x[i - 1], r[i - 1]);
		}
		if (i + 1 < n) {
			rg[i] = x[i] + getD(r[i], x[i + 1] - x[i], r[i + 1]);
		}
	}
	
/*	cerr << can(16) << endl;
	return;*/
	
	ld LF = 0, RG = 1e9;
	forn(_, 100) {
		ld mid = (LF + RG) / 2;
		if (can(mid) >= mid)
			LF = mid;
		else
			RG = mid;
	}
	printf("%.10lf\n", double(LF));
}

int main()
{
#ifdef SU1
	assert(freopen("input.txt", "rt", stdin));
//	assert(freopen("output.txt", "wt", stdout));
#endif

	cout << fixed << setprecision(10);
	cerr << fixed << setprecision(5);

	while (read())
		solve();
	
#ifdef SU1
	cerr << "=== TIME : " << clock() << " ===" << endl;
#endif
	return 0;
}
